<?php

namespace App\Amqp\Consumer;

use App\Constants\GuildCode;
use App\Model\Guild\GuildAccountDaily;
use App\Model\Guild\GuildManage;
use App\Model\GuildManage\GuildBalance;
use App\Model\GuildManage\GuildBalanceDaily;
use Hyperf\Amqp\Annotation\Consumer;
use Hyperf\Amqp\Message\ConsumerMessage;
use Hyperf\Amqp\Message\Type;
use Hyperf\Amqp\Result;
use Hyperf\Utils\HigherOrderTapProxy;
use PhpAmqpLib\Message\AMQPMessage;
use Hyperf\DbConnection\Db;

/**
 * @Consumer(exchange="guildSettlement", routingKey="guildSettlement", queue="guildSettlement.send", name ="GuildSettlementConsumer", nums=1)
 */
class GuildSettlementConsumer extends ConsumerMessage
{
    /**
     * @var string
     */
    protected $type = Type::DIRECT;

    /**
     * 结算单独公会
     * @param $data
     * @param AMQPMessage $message
     * @return string
     */
    public function consumeMessage($data, AMQPMessage $message): string
    {
        try {
            if (!$data['guild_id']) {
                log_error('GuildSettlementConsumer:error:NoGuildId:data:' . json_encode($data));
                return Result::ACK;
            }

            $guildId = $data['guild_id'];

            $guildInfo = (new GuildManage)->where([
                ['id', '=', $guildId],
            ])->first();

            //如果没有这个工会 或者这个工会的状态不等于1
            if (empty($guildInfo)) {
                log_error('GuildSettlementConsumer:error:NoGuild:guild_id:' . $guildId);
                return Result::ACK;
            }

            if ($guildInfo->status != 1) {
                log_info('GuildSettlementConsumer:info:GuildStatusError:guild_id:' . $guildId);
                return Result::ACK;
            }

            $dailyInfoIds = (new GuildBalanceDaily)->getDateColumnByGuildId($guildId);
            if (!empty($dailyInfoIds)) {
                log_info('GuildSettlementConsumer:info:GuildDailyYetSettlement:guild_id:' . $guildId);
                return Result::ACK;
            }

            $unlockBalance = $this->getAuditData($guildId);
            $lockBalance = $this->getLockData($guildId);
            $balanceInfo = (new GuildBalance)->getBalanceInfoByGuildId($guildId);

            Db::beginTransaction();

            $guildBalanceDailyModel = (new GuildBalanceDaily);
            $guildBalanceDailyModel->dt = date('Y-m-d', strtotime("-1 day"));
            $guildBalanceDailyModel->guild_manage_id = $guildInfo['id'];
            $guildBalanceDailyModel->have_access_balance = $unlockBalance;
            $guildBalanceDailyModel->audit_access_balance = $lockBalance;
            $guildBalanceDailyModel->save();

            if ($lockBalance == 0 && $balanceInfo == 0) {
                log_info('GuildSettlementConsumer:info:NoSettlement0:guild_id:' . $guildId);
                Db::commit();
                return Result::ACK;
            }

            if (empty($balanceInfo)) {
                $balanceModel = new GuildBalance();

                $balanceModel->user_id = $guildInfo['user_id'];
                $balanceModel->guild_manage_id = $guildInfo['id'];
                $balanceModel->have_access_balance = $unlockBalance;
                $balanceModel->audit_access_balance = $lockBalance;

                $updateType = 1;

                $updateCreateRes = $balanceModel->save();
            } else {
                $balanceInfo->have_access_balance = bcadd($balanceInfo->have_access_balance, $unlockBalance, 2);
                $balanceInfo->audit_access_balance = bcadd(bcsub($balanceInfo->audit_access_balance, $unlockBalance, 2), $lockBalance, 2);

                if ($balanceInfo->user_id == 0 && $guildInfo['user_id'] != 0) {
                    $balanceInfo->user_id = $guildInfo['user_id'];
                }

                $updateType = 2;

                $updateCreateRes = $balanceInfo->save();
            }

            if (!$updateCreateRes) {
                Db::rollBack();
                log_error('GuildSettlementConsumer:error:GuildBalanceSaveError:guild_id:' . $guildId . ':data:' . json_encode($balanceInfo) . ':type:' . $updateType);
                return Result::ACK;
            }

            Db::commit();

            return Result::ACK;
        } catch (\Throwable $exception) {
            var_dump($exception->getMessage());
            Db::rollBack();
            return Result::REQUEUE;
        }
    }

    /**
     * 获取前几日锁定的值
     * @param $guildId
     * @return HigherOrderTapProxy|int|mixed|null
     */
    private function getAuditData($guildId)
    {
        if (date('Y-m-d') <= GuildCode::BEGIN_DATA) {
            return 0;
        }

        $auditBalance = (new GuildBalanceDaily)->getAuditInfoByGuildId($guildId);
        if (empty($auditBalance)) {
            return 0;
        }

        return $auditBalance->audit_access_balance ?? 0;
    }

    /**
     * 获取锁定数据
     * @param $guildId
     * @return int|string
     */
    private function getLockData($guildId)
    {
        if (date('Y-m-d') <= GuildCode::BEGIN_DATA) {
            return 0;
        }

        $yesterdayData = (new GuildAccountDaily)->getYesterdayDataByGuild($guildId);
        if (empty($yesterdayData)) {
            return 0;
        }

        $baseIncome = $yesterdayData->voice_income
            + $yesterdayData->video_income
            + $yesterdayData->msg_income
            + $yesterdayData->gift_income;

        $inviteIncome = $yesterdayData->invite_recharge_income;

        $share = $yesterdayData->share_ratio;

        return bcdiv(bcadd(bcmul($baseIncome, $share, 2), bcmul($inviteIncome, $share, 2), 2), 10, 2) ?? 0;
    }
}